<?php

namespace App\Services;

use App\Exceptions\SmsSendFailException;
use App\Exceptions\InvalidRequestException;
use App\Handlers\Sms\CropSms;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class SmsService
{

    protected $sms_config;
    protected $easySms;
    protected $accessToken;
    protected $is_open = true;
    protected $is_debug = false;
    protected $debug_email = '';
    protected $debug_phone = '';

    public function __construct()
    {
        # 短信未开启
        if (!env('IS_OPEN_SMS', false)) {
            $this->is_open = false;
        }

        # 环境变量测试模式
        if (env('SMS_DEBUG', false)) {
            $this->is_debug = true;
            $this->debug_email = env('SMS_DEBUG_EMAIL', '');
            $this->debug_phone = env('SMS_DEBUG_PHONE', '');
        }

        if (!$this->is_open) {
            $this->easySms = null;
            $this->accessToken = ['access_token' => ''];
        } else {
            if (!env('SMS_APP_ID') || !env('SMS_APP_SECRET')) {
                throw new SmsSendFailException('无法使用');
            }    
            $this->easySms = new CropSms(env('SMS_APP_ID'), env('SMS_APP_SECRET'));
            $this->easySms->getAppToken();
            $this->accessToken = $this->easySms->getAccessToken();
            // $this->accessToken = $this->easySms->accessToken();
        }
    }

    public function debugAccessToken()
    {
        return $this->accessToken;
    }

    /**
     * 发送验证码
     */
    public function sendCode($phone)
    {
        $code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);

        $send_info = ['userMob' => $phone];
        $receiverLocalUser = [$send_info];

        $expiredAt = now()->addMinutes(10);

        //换成10分钟过期
        Cache::put('sms_key_'.$phone, ['phone' => $phone, 'code' => $code], $expiredAt);

        $code = '您的验证码为：'. $code . '，如非本人操作，请忽略。';

        $this->sendPushed($receiverLocalUser, '验证码', $code);

    }

    private function replaceDebugInfo($receiverLocalUser)
    {
        $new_receiverLocalUser = [];
        if (count($receiverLocalUser) > 0) {
            $new_receiverLocalUser[0] = [];
            if (isset($receiverLocalUser[0]['userEmail']) && $this->debug_email) {
                $new_receiverLocalUser[0]['userEmail'] = $this->debug_email;
            }
            if (isset($receiverLocalUser[0]['userMob']) && $this->debug_phone) {
                $new_receiverLocalUser[0]['userMob'] = $this->debug_phone;
            }
        }
        return $new_receiverLocalUser;
    }

    public function sendPushed($receiverLocalUser, $messageTitle, $messageContent)
    {
        $data = [
            'messageTitle' => $messageTitle,
            'messageContent' => $messageContent,
            "receiverLocalUser" => $receiverLocalUser,
        ];
        
        if (!$this->is_open) {
            Log::debug('sendPushed：', $data);
            return;
        }

        if ($this->is_debug) {
            Log::debug('sendPushed：', $data);
            $data['receiverLocalUser'] = $this->replaceDebugInfo($receiverLocalUser);
        }

        $accessToken = $this->accessToken;
        try {
            $result = $this->easySms->postSms(json_encode($data), $accessToken['access_token']);
            if ($result['code'] === 0) {

            } else {
                throw new SmsSendFailException('短信发送失败');
            }
        } catch (\Exception $exception) {
            $message = $exception->getMessage();
            throw new SmsSendFailException('发送失败');
        }
    }

    /**
     * 验证码是否有效
     */
    public static function verifyCode($code, $phone)
    {
        $verifyData = Cache::get('sms_key_'.$phone);

        if (!$code) {
            throw new InvalidRequestException('验证码必须填写');
        }

        # 短信验证码测试
        if (!env('IS_OPEN_SMS', false) || env('SMS_DEBUG_PHONE', '') == '15700098516') {
            if ($code == '111111') {
                return true;
            }
        }

        if (!$verifyData) {
            throw new InvalidRequestException('验证码已失效');
        }

        if (!hash_equals($verifyData['code'], $code) ||
            !hash_equals($verifyData['phone'], $phone)
        ) {
            throw new InvalidRequestException('验证码错误');
        }
    }

    /**
     * 发邮件
     * @param $receiverLocalUser
     * @param $messageTitle
     * @param $messageContent
     * @throws SmsSendFailException
     */
    public function sendEmail($receiverLocalUser, $messageTitle, $messageContent, $messageFromAddress="", $messageFromName="")
    {
        $data = [
            'messageTitle' => $messageTitle,
            'messageContent' => $messageContent,
            "messageFromAddress" => $messageFromAddress,
            "messageFromName" => $messageFromName,
            "receiverLocalUser" => $receiverLocalUser,
        ];

        if (!$this->is_open) {
            Log::debug('sendEmail：', $data);
            return;
        }

        if ($this->is_debug) {
            Log::debug('sendEmail：', $data);
            $data['receiverLocalUser'] = $this->replaceDebugInfo($receiverLocalUser);
        }

        $accessToken = $this->accessToken;
//        \Log::debug('data', $data);
        try {

            $result = $this->easySms->postSms(json_encode($data), $accessToken['access_token']);
            // \Log::debug('短信发送成功：', $result);
            if ($result['code'] === 0) {

            } else {
//                \Log::debug('短信发送失败：', $result);
                throw new SmsSendFailException('短信发送失败');
            }
        } catch (\Exception $exception) {
            $message = $exception->getMessage();
//            \Log::debug('短信发送失败：' . $message);
            throw new SmsSendFailException('发送失败');
        }
    }

}
